/*--------------------------------------------------------------------
 * execPartition.h
 *		POSTGRES分区执行器接口
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *		src/include/executor/execPartition.h
 *--------------------------------------------------------------------
 */

#ifndef EXECPARTITION_H
#define EXECPARTITION_H

#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "partitioning/partprune.h"

/* 有关定义，请参阅 execPartition.c。 */
typedef struct PartitionDispatchData *PartitionDispatch;
typedef struct PartitionTupleRouting PartitionTupleRouting;

extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(EState *estate,
															 Relation rel);
extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate,
										ResultRelInfo *rootResultRelInfo,
										PartitionTupleRouting *proute,
										TupleTableSlot *slot,
										EState *estate);
extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
									PartitionTupleRouting *proute);


/*
 * PartitionedRelPruningData - 每个分区表的数据，用于运行时修剪
 * 分区。对于多级分区表，我们为最上层分区和每个非叶子子分区各有一个。
 *
 * subplan_map[] 和 subpart_map[] 的定义与 PartitionedRelPruneInfo 中相同 
 * （参见 plannodes.h）；请注意，这里，subpart_map 包含指向 
 * PartitionPruningData.partrelprunedata[] 的索引。
 *
 * nparts						subplan_map[] 和 subpart_map[] 的长度。
 * subplan_map					按分区索引的子计划索引，或 -1。
 * subpart_map					按分区索引的子部分索引，或 -1。
 * present_parts				一个 Bitmapset，表示我们有子计划或子部分的
 *								分区索引。
 * initial_pruning_steps		用于执行执行器启动修剪的 PartitionPruneSteps 列表。
 * exec_pruning_steps			用于执行每次扫描修剪的 PartitionPruneSteps 列表。
 * initial_context				如果 initial_pruning_steps 不是 NIL，包含
 *								执行这些步骤所需的详细信息。
 * exec_context					如果 exec_pruning_steps 不是 NIL，包含
 *								执行这些步骤所需的详细信息。
 */
typedef struct PartitionedRelPruningData
{
	int			nparts;
	int		   *subplan_map;
	int		   *subpart_map;
	Bitmapset  *present_parts;
	List	   *initial_pruning_steps;
	List	   *exec_pruning_steps;
	PartitionPruneContext initial_context;
	PartitionPruneContext exec_context;
} PartitionedRelPruningData;

/*
 * PartitionPruningData - 保存单个分区层次结构的所有运行时修剪信息，包含一个或多个分区。
 * partrelprunedata[] 是一个数组，顺序使得父级出现在其子级之前；特别是，第一条条目是
 * SQL 查询中实际命名的最上层分区。
 */
typedef struct PartitionPruningData
{
	int			num_partrelprunedata;	/* 数组条目的数量 */
	PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruningData;

/*
 * PartitionPruneState - 为计划节点执行运行时分区修剪所需的状态对象。
 *
 * 此结构可以附加到支持包含分区的任意子计划列表的计划类型，
 * 以便由于某些子句无法与子计划可能产生的任何元组匹配而允许消除子计划。
 *
 * execparamids			包含在任何 partprunedata 结构中找到的 PARAM_EXEC 参数的 paramids。
 *						每当这些参数的值更改时，必须重新进行修剪。
 * other_subplans		包含不属于任何 "partprunedata" 的子计划索引，
 *						例如，不是分区表的 UNION ALL 子项，
 *						或者计划者认为运行时修剪对分区表是无用的。
 *						这些必须不被修剪。
 * prune_context		用于执行分区修剪函数的短期内存上下文。
 * do_initial_prune		如果在执行器启动期间（在任何层级）应执行修剪，则为 true。
 * do_exec_prune		如果在执行器运行期间（在任何层级）应执行修剪，则为 true。
 * num_partprunedata	"partprunedata" 数组中的项目数量。
 * partprunedata		计划的分区关系的 PartitionPruningData 指针数组，
 *						每个需要运行时修剪的分区层次结构一个。
 */
typedef struct PartitionPruneState
{
	Bitmapset  *execparamids;
	Bitmapset  *other_subplans;
	MemoryContext prune_context;
	bool		do_initial_prune;
	bool		do_exec_prune;
	int			num_partprunedata;
	PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruneState;

extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate,
													 int n_total_subplans,
													 PartitionPruneInfo *pruneinfo,
													 Bitmapset **initially_valid_subplans);
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate,
										   bool initial_prune);

#endif							/* EXECPARTITION_H */
